package com.ljw.hmall.order.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljw.hmall.clients.AddressClient;
import com.ljw.hmall.clients.ItemClient;
import com.ljw.hmall.order.basecontext.MyThreadLocal;
import com.ljw.hmall.order.mapper.OrderDetailMapper;
import com.ljw.hmall.order.mapper.OrderLogisticsMapper;
import com.ljw.hmall.order.mapper.OrderMapper;
import com.ljw.hmall.order.pojo.Order;
import com.ljw.hmall.order.pojo.OrderDetail;
import com.ljw.hmall.order.pojo.OrderLogistics;
import com.ljw.hmall.order.pojo.OrderParam;
import com.ljw.hmall.order.service.IOrderService;
import com.ljw.hmall.order.utils.IdWorker;
import com.ljw.hmall.pojo.Address;
import com.ljw.hmall.pojo.Item;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

@Slf4j
@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {
    @Autowired
    OrderMapper orderMapper;

    @Autowired
    ItemClient itemClient;

    @Autowired
    OrderDetailMapper orderDetailMapper;
    @Autowired
    AddressClient addressClient;

    @Autowired
    OrderLogisticsMapper orderLogisticsMapper;

    @Autowired
    RabbitTemplate rabbitTemplate;
    //结合seata完成分布式事务
    @GlobalTransactional
    @Override
    public Long placeOrder(OrderParam orderParam) {

        //使用雪花算法工具类生成orderId
        IdWorker idWorker = new IdWorker(1, 1);
        long orderId = idWorker.nextId();
        Item item = itemClient.getById(orderParam.getItemId());
        Long price = item.getPrice();
        Integer num = orderParam.getNum();
        long totalFee=price*num;
        //开始构建订单对象
        Order order = new Order();
        order.setId(orderId);
        order.setTotalFee(totalFee);
        order.setPaymentType(orderParam.getPaymentType());
        String uId = (String) MyThreadLocal.get();
        Long userId = Long.valueOf(uId);
        order.setUserId(userId);
        order.setStatus(1);
        Date date = new Date();
        order.setCreateTime(date);

        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DAY_OF_MONTH,1);
        //获取到明天的这个时候
        Date tomorrow = c.getTime();
        order.setConsignTime(tomorrow);
        order.setUpdateTime(date);
        orderMapper.insert(order);
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setCreateTime(date);
        orderDetail.setOrderId(orderId);
        orderDetail.setImage(item.getImage());
        orderDetail.setItemId(item.getId());
        orderDetail.setNum(orderParam.getNum());
        orderDetail.setPrice(item.getPrice());
        orderDetail.setSpec(item.getSpec());
        orderDetail.setUpdateTime(date);
        orderDetail.setName(item.getName());


        orderDetailMapper.insert(orderDetail);
        Address address = addressClient.findAddressById(orderParam.getAddressId());
        OrderLogistics orderLogistics = new OrderLogistics();
        orderLogistics.setOrderId(orderId);
        orderLogistics.setCity(address.getCity());
        orderLogistics.setContact(address.getContact());
        orderLogistics.setCreateTime(date);
        orderLogistics.setProvince(address.getProvince());
        orderLogistics.setLogisticsNumber(""+System.currentTimeMillis());
        orderLogistics.setLogisticsCompany("旺仔公司");
        orderLogistics.setMobile(address.getMobile());
        orderLogistics.setStreet(address.getStreet());
        orderLogistics.setTown(address.getTown());
        orderLogistics.setUpdateTime(date);

        orderLogisticsMapper.insert(orderLogistics);
        //下单就减库存，如果过期未支付，再取消订单，恢复库存
        itemClient.updateById(item.getId(),orderParam.getNum());
        System.out.println("下单成功...");
        //下单成功后发送一个延迟30分钟才接到的延迟消息消息，取消过期为支付订单
        String uid = (String) MyThreadLocal.get();
        System.err.println("用户的id为:"+uid);

        Message message = MessageBuilder
                .withBody((uid+","+ orderId).getBytes(StandardCharsets.UTF_8))
                .setExpiration("10000")
                .build();


        //消息ID，防止消息之间的ack产生冲突
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());

        rabbitTemplate.convertAndSend("normal.direct","ttl",message,correlationData);
        log.info("订单过时取消消息发送成功...");
        return orderId;
    }
}
